package com.fingard.dsp.bank.directbank.cib01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.bankInterface.IElecBillTrans;
import com.fingard.dsp.bank.reqrespobj.elecbilltrans.*;
import com.fingard.dsp.bank.reqrespobj.elecbilltrans.detail.*;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import com.ibm.wsdl.util.xml.QNameUtils;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.util.*;

/**
 * Created by F on 2018/9/11.
 */
@Component("CIB01ElecBillTrans")
public class CIB01ElecBillTrans extends CIB01Base implements IElecBillTrans {
    private static final String INSERTRECEIPT = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,BUSITYPE,TRANSDATE,REQSEQID,BANKREQSEQID) values (?,?,?,?,?,?);";

    @Override
    public RetAtsB003BillRespSubmit D_B003_BillResp_Submit(ReqB003BillRespSubmit query) throws Exception {
        //通用签收/拒签请求
        return BillPublicrReply(query);
    }
    //票据通用应答（电票和票据池通用一个银行接口一个改都需要改）
    public RetAtsB003BillRespSubmit BillPublicrReply(ReqB003BillRespSubmit query) throws Exception {
        RetAtsB003BillRespSubmit retAts = new RetAtsB003BillRespSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB003BillRespSubmitDetail detail = new RetAtsB003BillRespSubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//<SECURITIES_MSGSRQV1>	请求服务指令消息集	必输
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                <EBSIGNTRNRQ>	服务标识	必输
                xmlWriter.writeStartElement("EBSIGNTRNRQ");
//                        <TRNUID/>	客户端交易的唯一流水号
                String trnuId = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trnuId);
//                建议值为YYYYMMDD+序号，最长30位	必输
//                <RQBODY>	消息报文体	非必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//                <TOTALAMT/>	票据总金额,17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", query.detail.billAmt);
//                        <SIGNDATE/>	签收日期,YYYY-MM-DD	必输
                xmlWriter.writeElementString("SIGNDATE", Format.Date10Format.format(new Date()));
//                        <ACCTID/>	签收人账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.actNum);
//                        <SIGNRSLT/>	签收结果,4位
//                        (SU00:同意签收, SU01:拒绝签收)	必输
                String respFlag;
                if ("1".equals(query.detail.respFlag)) {
                    respFlag = "SU00";
                } else {
                    respFlag = "SU01";
                }
                xmlWriter.writeElementString("SIGNRSLT", respFlag);
//                        <RJRSN/>	拒签理由, 4位见附录:拒付理由/拒签理由	非必输
//                N--DC0(N-1) 99--DC09
//                if(StringHelper.hasAnyChar(query.detail.unPayCode)) {
//                    String unPayCode;
//                    int i = Integer.valueOf(query.detail.unPayCode);
//                    if (99 != i) {
//                        unPayCode = "DC0" + (i - 1);
//                    } else {
//                        unPayCode = "DC09";
//                    }
//                    xmlWriter.writeElementString("RJRSN", unPayCode);
//                }
                Set<String> respTypeSet = new LinkedHashSet<String>();
                respTypeSet.add("1");   //承兑应答
                respTypeSet.add("2");   //收票应答
                respTypeSet.add("3");   //背书转让应答
                respTypeSet.add("4");   //回购式贴现赎回应答
                respTypeSet.add("5");   //质押解除应答
                respTypeSet.add("7");   //保证应答
                respTypeSet.add("8");   //同意清偿应答
                respTypeSet.add("9");   //质押签收
                respTypeSet.add("10");  //贴现签收
                if ("SU01".equals(respFlag)) {
                    if (respTypeSet.contains(query.detail.respType)) {
                        xmlWriter.writeElementString("RJRSN", "DC09");
//                  <RJMEMO/>	拒签备注,最大256位，兴业银行签收拒绝时，拒绝理由为必输，和客户及银行沟通后理由填其它
                        xmlWriter.writeElementString("RJMEMO", "不符合要求");
                    } else {
                        if (StringHelper.hasAnyChar(query.detail.unPayCode)) {
                            String unPayCode;
                            int i = Integer.valueOf(query.detail.unPayCode);
                            if (99 != i) {
                                unPayCode = "DC0" + (i - 1);
                            } else {
                                unPayCode = "DC09";
                            }
                            xmlWriter.writeElementString("RJRSN", unPayCode);
//                        <RJMEMO/>	拒签备注,最大256位	非必输
                            xmlWriter.writeElementString("RJMEMO", query.detail.unPayMemo);
                        }
                    }
                }
//                        <SIGNMEMO/>	签收人备注,最大256位	非必输
                xmlWriter.writeElementString("SIGNMEMO", query.detail.memo);
//                        <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", query.detail.billAmt);
//                        <BUSINESSTYPE/>	业务类型,2位,见:附录3-业务类型对照表	必输
                String respType;
                //1-承兑应答 2-收票应答 3-背书转让应答 4-回购式贴现赎回应答 5-质押解除应答 6-提示付款应答
                //7-保证应答 8-同意清偿应,9-质押签收
                switch (Integer.valueOf(query.detail.respType)) {
//                    03  05 07 10 16 17 xx 31
                    case 1:
                        respType = "03";
                        break;
                    case 2:
                        respType = "05";
                        break;
                    case 3:
                        respType = "07";
                        break;
                    case 4:
                        respType = "10";
                        break;
                    case 5:
                        respType = "16";
                        break;
                    case 6:
                        respType = "17";
                        break;
                    case 7:
                        throw new Exception("不明确是出票保证，承兑保证还是背书保证，暂不对接该端口");
                    case 8:
                        respType = "21";
                        break;
                    case 9:
                        respType = "15";
                        break;
                    default:
                        throw new Exception("业务类型未知:" + query.detail.respType);
                }
                xmlWriter.writeElementString("BUSINESSTYPE", respType);
//                <ENTRSPAY/>	到期无条件支付委托,4位只能是CC00	必输
                xmlWriter.writeElementString("ENTRSPAY", "CC00");
//                <AGRM/>	协议号,承兑,贴现时有效,0-30位	非必输
                xmlWriter.writeElementString("AGRM", query.detail.protocolNo);
//                <BIZFLAG/>	业务标识号,最大35位，待签收票据查询中获取	必输
                xmlWriter.writeElementString("BIZFLAG", query.detail.busiNo);
//                </CONTENT>
//                </RQBODY>
//                </EBSIGNTRNRQ>
//                </SECURITIES_MSGSRQV1>
                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBSIGNTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trnuId});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBSIGNTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBSIGNTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBSIGNTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                            detail.reqSeqID = query.detail.reqSeqID;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBSIGNTRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //出票登记
    @Override
    public RetAtsB101BillApplySubmit D_B101_BillResp_Submit(ReqB101BillApplySubmit query) throws Exception {
        RetAtsB101BillApplySubmit retAts = new RetAtsB101BillApplySubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB101BillApplySubmitDetail detail = new RetAtsB101BillApplySubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//            <SECURITIES_MSGSRQV1>
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                    <EBDRAWTRNRQ>		必输
                xmlWriter.writeStartElement("EBDRAWTRNRQ");
//            <TRNUID/>	客户端交易的唯一流水号,建议值为YYYYMMDD+序号，最长30位	必输
                String trnuid = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trnuid);
//            <RQBODY>		非必
                xmlWriter.writeStartElement("RQBODY");
//                    <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//            <TOTALAMT/>	票据总金额, 17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", query.detail.billAmt);
//                    <TYPE/>	交易类型,2位
//            01(出票登记)
//                    02(出票,保证)
//            03(出票,承兑)
//            04(出票,保证,承兑)
//            05(出票,承兑,提示收票)
//            06(出票,保证,自动提示承兑,自动提示收票)	必输
                String type;
                if ("1".equals(query.detail.autoPromptReceipt)) {
                    type = "05";
                } else if ("1".equals(query.detail.autoPromptAccept)) {
                    type = "03";
                } else {
                    type = "01";
                }
                xmlWriter.writeElementString("TYPE", type);
//                    <BILLTYPE/>	票据类型,4位(AC01:银票,AC02:商票)	必输
                String billType;
                if ("1".equals(query.detail.billType)) {
                    billType = "AC01";
                } else {
                    billType = "AC02";
                }
                xmlWriter.writeElementString("BILLTYPE", billType);
                //出票申请账户代号,最大32位
                xmlWriter.writeElementString("DRAWACCTID", query.detail.drawAct);
//               <CRDINFO>	出票人评级信息	非必输
//                xmlWriter.writeStartElement("CRDINFO");
//            <CRDLVL/>	信用级别	非必输
//                xmlWriter.writeElementString("CRDLVL", query.detail.creditLv);
//                    <RTGAGNCY/>	评级机构	非必输
//                xmlWriter.writeElementString("RTGAGNCY", query.detail.gradeAgent);
//            <RTGDUEDATE/>	评级到期日	非必输
//                xmlWriter.writeElementString("RTGDUEDATE", query.detail.gradeDueDate);
//                    </CRDINFO>
//                xmlWriter.writeEndElement();
//            <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                    <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//            <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", query.detail.billAmt);
                Date issDate = Format.DateTime21Format.parse(query.detail.issDate);
                if (-1 == DateHelper.compareDay(issDate, new Date())) {
                    throw new Exception("判断出票日期不得早于当日:" + query.detail.issDate);
                }
                //                    <DRAWDATE/>	出票日,YYYY-MM-DD	必输
                xmlWriter.writeElementString("DRAWDATE", Format.Date10Format.format(issDate));//出票日(8)
                Date expiryDate = Format.DateTime21Format.parse(query.detail.dueDate);
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(issDate);
                calendar.add(Calendar.YEAR, 1);
                if (-1 == (DateHelper.compareDay(calendar.getTime(), expiryDate))) {
                    throw new Exception("到期日与出票日的时间间隔不得超过一年");
                }
//                    <DUEDATE/>	票据到期日,YYYY-MM-DD	必输
                xmlWriter.writeElementString("DUEDATE", Format.Date10Format.format(expiryDate));
//                    <NEGTBL/>	可否转让标识,4位(EM00:可再转让,EM01:不可再转让)	必输
                String transFlag;
                if ("1".equals(query.detail.transFlag)) {
                    transFlag = "EM00";
                } else {
                    transFlag = "EM01";
                }
                xmlWriter.writeElementString("NEGTBL", transFlag);
//                    <ISCIB/>	收款账户代号是否兴业账户代号,1位(Y:是,N:否)	必输
                xmlWriter.writeElementString("ISCIB", "1".equals(query.detail.payeeSameBnk) ? "Y" : "N");
//                    <PAYEEACCT>	收款账户信息	必输
                xmlWriter.writeStartElement("PAYEEACCT");
//            <ACCTID/>	账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.payeeAct);
//                    <NAME/>	账户名称,最大60位	必输
                xmlWriter.writeElementString("NAME", query.detail.payeeName);
//                    <BANKNUM/>	开户行号,最大12位	必输
                xmlWriter.writeElementString("BANKNUM", query.detail.payeeBnkCode);
//                    </PAYEEACCT>
                xmlWriter.writeEndElement();
//            <ACACCT>	承兑人账户信息	必输
                xmlWriter.writeStartElement("ACACCT");
//                    <ACCTID/>	账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.accpAct);
//                    <NAME/>	账户名称,最大60位	必输
                xmlWriter.writeElementString("NAME", query.detail.accpName);
//                    <BANKNUM/>	开户行号,最大12位	必输
                xmlWriter.writeElementString("BANKNUM", query.detail.accpBnkCode);
//                    </ACACCT>
                xmlWriter.writeEndElement();
//            <ENTRSPAY/>	到期无条件支付委托,4位只能是CC00	必输
                xmlWriter.writeElementString("ENTRSPAY", "CC00");
//            <CONTRACTID/>	交易合同号,最大30位	非必输
                xmlWriter.writeElementString("CONTRACTID", query.detail.contractNo);
//                    <INVCNO/>	发票号码,最大30位	非必输
                xmlWriter.writeElementString("INVCNO", query.detail.invoiceNo);
//                    <DRAWMEMO/>	信息登记备注,最大256位	非必输
                xmlWriter.writeElementString("DRAWMEMO", query.detail.memo);
//                    </CONTENT>
//            </RQBODY>
//            </EBDRAWTRNRQ>
//            </SECURITIES_ MSGSRQV1>
                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBDRAWTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trnuid});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        detail.respCode = "0";
                        detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDRAWTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                        detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDRAWTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                        detail.payInfoCode = detail.transState;
                    } else {
                        detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDRAWTRNRS/TRNUID");
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //提示承兑
    @Override
    public RetAtsB102BillAccpSubmit D_B102_BillResp_Submit(ReqB102BillAccpSubmit query) throws Exception {
        RetAtsB102BillAccpSubmit retAts = new RetAtsB102BillAccpSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB102BillAccpSubmitDetail detail = new RetAtsB102BillAccpSubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>		必输
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                        <EBACPTTRNRQ>		必输
                xmlWriter.writeStartElement("EBACPTTRNRQ");
//                <TRNUID/>	客户端交易的唯一流水号
                String trnuid = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trnuid);
//                建议值为YYYYMMDD+序号，最长30位	必输
//                <RQBODY>		非必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//                <TOTALAMT/>	票据总金额,17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", query.detail.billAmt);
//                        <ACCTID/>	出票人账户代号	必输
                xmlWriter.writeElementString("ACCTID", query.detail.actNum);
//                <BILLTYPE/>	票据种类	必输
                String billType;
                if ("1".equals(query.detail.billType)) {
                    billType = "AC01";
                } else {
                    billType = "AC02";
                }
                xmlWriter.writeElementString("BILLTYPE", billType);
//                        <MEMO/>	出票人备注	非必输
                xmlWriter.writeElementString("MEMO", query.detail.memo);
//                <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                        <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", query.detail.billAmt);
//                        <ENTRSPAY/>	到期无条件支付委托,4位只能是CC00	必输
                xmlWriter.writeElementString("ENTRSPAY", "CC00");
//                <CONTRACTID/>	交易合同号,最大30位	非必输
                xmlWriter.writeElementString("CONTRACTID", query.detail.contractNo);
//                        <INVCNO/>	发票号码,最大30位	非必输
                xmlWriter.writeElementString("INVCNO", query.detail.invoiceNo);
//                        <ACPTAMT/>	承兑金额,17位(15整数位,2小数位)
                xmlWriter.writeElementString("ACPTAMT", query.detail.billAmt);
//                (暂只能是票面金额)	非必输
//                        </CONTENT>
//                </RQBODY>
//                </EBACPTTRNRQ>
//                </SECURITIES_ MSGSRQV1>
                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBACPTTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trnuid});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBACPTTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBACPTTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBACPTTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBACPTTRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }


                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //出票撤票
    @Override
    public RetAtsB103BillRetSubmit D_B103_BillResp_Submit(ReqB103BillRetSubmit query) throws Exception {
        RetAtsB103BillRetSubmit retAts = new RetAtsB103BillRetSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB103BillRetSubmitDetail detail = new RetAtsB103BillRetSubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>		必输.
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                        <EBCANCLTRNRQ>		必输
                xmlWriter.writeStartElement("EBCANCLTRNRQ");
//                <TRNUID/>	客户端交易的唯一流水号
                String trunid = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trunid);
//                建议值为YYYYMMDD+序号，最长30位	必输
//                <RQBODY>		非必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//                <TOTALAMT/>	票据总金额,17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", query.detail.billAmt);
//                        <BILLTYPE/>	票据类型,4位(AC01:银票,AC02:商票)	必输
                String billType;
                if ("1".equals(query.detail.billType)) {
                    billType = "AC01";
                } else {
                    billType = "AC02";
                }
                xmlWriter.writeElementString("BILLTYPE", billType);
//                        <ACCTID/>	操作人账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.actNum);
//                        <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", query.detail.billAmt);
//                        </CONTENT>
//                </RQBODY>
//                </EBCOLLTRNRQ>
//                </SECURITIES_MSGSRQV1>
                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBCOLLTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trunid});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCANCLTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCANCLTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCANCLTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCANCLTRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //提示收票
    @Override
    public RetAtsB104BillReceSubmit D_B104_BillResp_Submit(ReqB104BillReceSubmit query) throws Exception {
        RetAtsB104BillReceSubmit retAts = new RetAtsB104BillReceSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB104BillReceSubmitDetail detail = new RetAtsB104BillReceSubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>		必输.
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                        <EBCOLLTRNRQ>		必输
                xmlWriter.writeStartElement("EBCOLLTRNRQ");
//                <TRNUID/>	客户端交易的唯一流水号
                String trunid = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trunid);
//                建议值为YYYYMMDD+序号，最长30位	必输
//                <RQBODY>		非必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//                <TOTALAMT/>	票据总金额,17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", query.detail.billAmt);
                //  <ACCTID/>	操作人账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.actNum);
//                        <BILLTYPE/>	票据类型,4位(AC01:银票,AC02:商票)	必输
                String billType;
                if ("1".equals(query.detail.billType)) {
                    billType = "AC01";
                } else {
                    billType = "AC02";
                }
                xmlWriter.writeElementString("BILLTYPE", billType);
//                <MEMO/>	备注,最大256位	非必输
                xmlWriter.writeElementString("MEMO", query.detail.memo);
//                        <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", query.detail.billAmt);
//                        </CONTENT>
//                </RQBODY>
//                </EBCOLLTRNRQ>
//                </SECURITIES_MSGSRQV1>
                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBCOLLTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trunid});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCOLLTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCOLLTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCOLLTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCOLLTRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //背书转让
    @Override
    public RetAtsB105BillEndoSubmit D_B105_BillResp_Submit(ReqB105BillEndoSubmit query) throws Exception {
        RetAtsB105BillEndoSubmit retAts = new RetAtsB105BillEndoSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB105BillEndoSubmitDetail detail = new RetAtsB105BillEndoSubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>	请求服务指令消息集	必输
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                <EBENDRSTRNRQ>	服务标识	必输
                xmlWriter.writeStartElement("EBENDRSTRNRQ");
//                        <TRNUID/>	客户端交易的唯一流水号
                String trnuid = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trnuid);
//                建议值为YYYYMMDD+序号，最长30位	必输
//                <RQBODY>	消息报文体	必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//                <TOTALAMT/>	票据总金额,17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", query.detail.billAmt);
//                        <APPDATE/>	背书申请日期
                xmlWriter.writeElementString("APPDATE", Format.Date10Format.format(new Date()));
//                        <BILLTYPE/>	票据类型,4位(AC01:银票,AC02:商票) 必输
                String billType;
                if ("1".equals(query.detail.billType)) {
                    billType = "AC01";
                } else {
                    billType = "AC02";
                }
                xmlWriter.writeElementString("BILLTYPE", billType);
//                        <ENDRSRACCTID/>	背书人账户代号,最大32位	必输
                xmlWriter.writeElementString("ENDRSRACCTID", query.detail.actNum);
//                        <ENDRSEISCIB/>	被背书人账户代号是否兴业账户代号,1位(Y:是,N:否)	必输
                xmlWriter.writeElementString("ENDRSEISCIB", "1".equals(query.detail.receSameBank) ? "Y" : "N");
//                        <ENDRSEACCT>	被背书人账户信息	必输
                xmlWriter.writeStartElement("ENDRSEACCT");
//                <ACCTID/>	账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.receAct);
//                        <NAME/>	账户名称,最大60位	必输
                xmlWriter.writeElementString("NAME", query.detail.receName);
//                        <BANKNUM/>	开户行名,最大12位	必输
                xmlWriter.writeElementString("BANKNUM", query.detail.receBnkCode);
//                        </ENDRSEACCT>
                xmlWriter.writeEndElement();
//                <NEGTBL/>	可否转让标识,4位
//                        (EM00:可再转让,EM01:不可再转让)	必输
                String transFlag;
                if ("1".equals(query.detail.transFlag)) {
                    transFlag = "EM00";
                } else {
                    transFlag = "EM01";
                }
                xmlWriter.writeElementString("NEGTBL", transFlag);
//                        <MEMO/>	备注,最大256位	非必输
                xmlWriter.writeElementString("MEMO", query.detail.memo);
//                        <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", query.detail.billAmt);
//                        </CONTENT>
//                </RQBODY>
//                </EBENDRSTRNRQ>
//                </SECURITIES_MSGSRQV1>
                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBENDRSTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trnuid});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBENDRSTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBENDRSTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBENDRSTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBENDRSTRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //贴现
    @Override
    public RetAtsB106BillDiscSubmit D_B106_BillResp_Submit(ReqB106BillDiscSubmit query) throws Exception {
        RetAtsB106BillDiscSubmit retAts = new RetAtsB106BillDiscSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB106BillDiscSubmitDetail detail = new RetAtsB106BillDiscSubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>		必输
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                        <EBDISCNTTRNRQ>		必输
                xmlWriter.writeStartElement("EBDISCNTTRNRQ");
//                        <TRNUID/>	客户端交易的唯一流水号
                String trnuId = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trnuId);
//                建议值为YYYYMMDD+序号，最长30位	必输
//                <RQBODY>	消息报文体	必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
                double billAmt = Double.valueOf(query.detail.billAmt);
//                <TOTALAMT/>	票据总金额,17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", String.format("%.2f", billAmt));
//                        <TRADETYPE/>	交易类型,4位
//                        (TT00:贴现,TT01:转贴现,TT02:再贴现)	非必输
                xmlWriter.writeElementString("TRADETYPE", "TT00");
//                        <APPDATE/>	申请日期,YYYY-MM-DD	必输
                xmlWriter.writeElementString("APPDATE", Format.Date10Format.format(new Date()));
//                        <BILLTYPE/>	票据类型,4位(AC01:银票,AC02:商票)	必输
                String billType;
                if ("1".equals(query.detail.billType)) {
                    billType = "AC01";
                } else {
                    billType = "AC02";
                }
                xmlWriter.writeElementString("BILLTYPE", billType);
//                        <ACCTFROM>
                xmlWriter.writeStartElement("ACCTFROM");
//                <ACCTID/>	账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.actNum);
//                        <NAME/>	账户名称,最大60位	必输
                xmlWriter.writeElementString("NAME", query.detail.discName);
//                        </ACCTFROM>
                xmlWriter.writeEndElement();
//                <ISCIB/>	贴入人账户代号是否兴业账户代号,1位
                //                        (Y:是,N:否)	必输
                xmlWriter.writeElementString("ISCIB", "1".endsWith(query.detail.receSameBnk) ? "Y" : "N");
//                        <ACCTTO>	贴入人账户信息	必输
                xmlWriter.writeStartElement("ACCTTO");
//                <ACCTID/>	账户代号,最大32位
                xmlWriter.writeElementString("ACCTID", query.detail.receAct);
//                        <NAME/>	账户名称,最大60位
                xmlWriter.writeElementString("NAME", query.detail.receName);
//                        <BANKNUM/>	开户行号,最大12位
                xmlWriter.writeElementString("BANKNUM", query.detail.receBnkCode);
//                        </ACCTTO>
                xmlWriter.writeEndElement();
//                <DISCNTTYPE/>	贴现类型,4位
//                        (RM00:买断式, RM01:回购式)	非必输
                String discType;
                if ("1".equals(query.detail.discType)) {
                    discType = "RM00";
                } else {
                    discType = "RM01";
                }
                xmlWriter.writeElementString("DISCNTTYPE", discType);
//                        <INTRSTRATE/>	贴现利率,7位百分数不含百分号
//                        (2位整数,5位小数)	必输
                xmlWriter.writeElementString("INTRSTRATE", String.format("%.5f", Double.valueOf(query.detail.discRate)));
//                        <NEGTBL/>	可否转让标识,4位
//                        (EM00:可再转让,EM01:不可再转让)	必输
                String transFlag;
                if ("1".equals(query.detail.transFlag)) {
                    billType = "EM00";
                } else {
                    billType = "EM01";
                }
                xmlWriter.writeElementString("NEGTBL", billType);


                //ATSES-29631 兴业电票贴现提示String index out of range: -1
                if (StringHelper.isNullOrEmpty(query.detail.repOpenDate) || StringHelper.isNullOrEmpty(query.detail.repDueDate)) {
//                              <REDMDATE>	赎回日期范围	非必输
                    xmlWriter.writeStartElement("REDMDATE");
//                <DTSTART/>	开始日期,YYYY-MM-DD
                    xmlWriter.writeElementString("DTSTART", query.detail.repOpenDate);
//                        <DTEND/>	截止日期,YYYY-MM-DD
                    xmlWriter.writeElementString("DTEND", query.detail.repDueDate);
//                        </REDMDATE>
                    xmlWriter.writeEndElement();
                }
//


//                <REDMINTRSTRATE/>	赎回利率,7位百分数不含百分号
//                        (2位整数,5位小数)	非必输
                String repRate = StringHelper.hasAnyChar(query.detail.repRate) ? query.detail.repRate : "";
                xmlWriter.writeElementString("REDMINTRSTRATE", StringHelper.hasAnyChar(repRate) ? String.format("%.5f", Double.valueOf(query.detail.repRate)) : repRate);
//                        <CONTRACTID/>	交易合同号,最大30位	非必输
                xmlWriter.writeElementString("CONTRACTID", query.detail.contractNo);
//                        <INVCNO/>	发票号码,最大30位	非必输
                xmlWriter.writeElementString("INVCNO", query.detail.invoiceNo);
//                        <MEMO/>	贴出人备注,最大256位	非必输
                xmlWriter.writeElementString("MEMO", query.detail.memo);
//                        <LQMODE/>	清算模式,4位
//                        (SM00:线上清算,SM01:线下清算)	必输
                String payType;
                if ("1".equals(query.detail.payType)) {
                    payType = "SM00";
                } else {
                    payType = "SM01";
                }
                xmlWriter.writeElementString("LQMODE", payType);
//                        <INACCTID/>	入账账户代号,最大32位	非必输
                xmlWriter.writeElementString("INACCTID", query.detail.actedAct);
//                        <INBANKNUM/>	入账行号,最大12位	非必输
                xmlWriter.writeElementString("INBANKNUM", query.detail.actedBnkCode);
//                        <PAYINTRMODE/>	贴现申请付息方式：1－卖方付息 2－买方付息
                if ("3".equals(query.detail.payInterestType)) {
                    throw new Exception("贴现付息方式不支持协议付息");
                }
//                转贴现申请与再贴现申请不必输入	非必输
//                xmlWriter.writeElementString("PAYINTRMODE",query.detail.payInterestType);
                xmlWriter.writeElementString("PAYINTRMODE", "1");
//                <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                        <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", String.format("%.2f", billAmt));
//                        <REALPAY/>	实付金额,17位(15整数位,2小数位)	必输
                double discAmt = Double.valueOf(query.detail.discAmt);
                xmlWriter.writeElementString("REALPAY", String.format("%.2f", discAmt));
//                        <REDMAMT/>	赎回金额,17位(15整数位,2小数位)	非必输
                String repAmt = StringHelper.hasAnyChar(query.detail.repAmt) ? query.detail.repAmt : "";
                xmlWriter.writeElementString("REDMAMT", StringHelper.hasAnyChar(repAmt) ? String.format("%.2f", Double.valueOf(query.detail.repRate)) : "");
//                        <DUEDATE/>	票据到期日，YYYY-MM-DD
//                贴现类型为RM00:买断式时必输	非必输
                if (discType.equals("RM00")) {
                    Date dueDate = Format.DateTime21Format.parse(query.detail.dueDate);
                    xmlWriter.writeElementString("DUEDATE", Format.Date10Format.format(dueDate));
                }
//                </CONTENT>
//                </RQBODY>
//                </EBDISCNTTRNRQ>
//                </SECURITIES_MSGSRQV1>
                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBDISCNTTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trnuId});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDISCNTTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDISCNTTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDISCNTTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDISCNTTRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //质押
    @Override
    public RetAtsB107BillPledSubmit D_B107_BillResp_Submit(ReqB107BillPledSubmit query) throws Exception {
        RetAtsB107BillPledSubmit retAts = new RetAtsB107BillPledSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB107BillPledSubmitDetail detail = new RetAtsB107BillPledSubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>	请求服务指令消息集	必输
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                        <EBIMPAWNTRNRQ>	服务标识	必输
                xmlWriter.writeStartElement("EBIMPAWNTRNRQ");
//                <TRNUID/>	客户端交易的唯一流水号
                String trunId = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trunId);
//                建议值为YYYYMMDD+序号，最长30位	必输
//                <RQBODY>	消息报文体	必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//                <TOTALAMT/>	票据总金额,17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", query.detail.billAmt);
//                        <APPDATE/>	质押申请日期,YYYY-MM-DD	必输
                xmlWriter.writeElementString("APPDATE", Format.Date10Format.format(new Date()));
//                        <ACCTFROM>	出质人账户代号,最大32位	必输
                xmlWriter.writeStartElement("ACCTFROM");
//                        <ACCTID/>
                xmlWriter.writeElementString("ACCTID", query.detail.actNum);
//                </ACCTFROM>
                xmlWriter.writeEndElement();
//                <BILLTYPE/>	票据类型,4位(AC01:银票,AC02:商票)	必输
                String billType;
                if ("1".equals(query.detail.billType)) {
                    billType = "AC01";
                } else {
                    billType = "AC02";
                }
                xmlWriter.writeElementString("BILLTYPE", billType);
//                        <ISCIB/>	质权人是否兴业账户,1位(Y:是,N:否)	必输
                xmlWriter.writeElementString("ISCIB", "1".equals(query.detail.receSameBnk) ? "Y" : "N");
//                        <ACCTTO>	质权人账户代号,最大60位	必输
                xmlWriter.writeStartElement("ACCTTO");
//                        <ACCTID/>	账户代号
                xmlWriter.writeElementString("ACCTID", query.detail.receAct);
//                        <NAME/>	账户名称
                xmlWriter.writeElementString("NAME", query.detail.receName);
//                        <BANKNUM/>	开户行行号
                xmlWriter.writeElementString("BANKNUM", query.detail.receBnkCode);
//                        </ACCTTO>
                xmlWriter.writeEndElement();
//                <MEMO/>	出质人备注	非必输
                xmlWriter.writeElementString("MEMO", query.detail.memo);
//                        <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", query.detail.billAmt);
//                        </CONTENT>
//                </RQBODY>
//                </EBIMPAWNTRNRQ>
//                </SECURITIES_MSGSRQV1>
                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBIMPAWNTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trunId});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBIMPAWNTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBIMPAWNTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBIMPAWNTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBIMPAWNTRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //提示付款
    @Override
    public RetAtsB108BillPaySubmit D_B108_BillResp_Submit(ReqB108BillPaySubmit query) throws Exception {
        RetAtsB108BillPaySubmit retAts = new RetAtsB108BillPaySubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB108BillPaySubmitDetail detail = new RetAtsB108BillPaySubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>		必输
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                        <EBCUEPAYTRNRQ>		必输
                xmlWriter.writeStartElement("EBCUEPAYTRNRQ");
//                        <TRNUID/>	客户端交易的唯一流水号;
                String trnuId = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trnuId);
//                建议值为YYYYMMDD+序号，最长30位	必输
//                <RQBODY>	消息报文体	非必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//                <TOTALAMT/>	票据总金额,17位(15整数位,2小数位) 	必输
                double billAmt = Double.valueOf(query.detail.billAmt);
                xmlWriter.writeElementString("TOTALAMT", String.format("%.2f", billAmt));
//                        <APPDATE/>	提示付款申请日期,YYYY-MM-DD	必输
                xmlWriter.writeElementString("APPDATE", Format.Date10Format.format(new Date()));
//                        <ACCTID/>	提示付款申请人账户代号,最大60位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.actNum);
//                        <CUETYPE/>	提示付款类型,2位
                String proPayType;
                if ("1".equals(query.detail.proPayType)) {
                    proPayType = "01";
                } else {
                    proPayType = "02";
                }
                xmlWriter.writeElementString("CUETYPE", proPayType);
//                        (01:正常提示付款,02:逾期提示付款)	必输
//                        <BILLTYPE/>	票据类型,4位(AC01:银票,AC02:商票)	必输
                String billType;
                if ("1".equals(query.detail.billType)) {
                    billType = "AC01";
                } else {
                    billType = "AC02";
                }
                xmlWriter.writeElementString("BILLTYPE", billType);
//                        <LQMODE/>	清算模式,4位
//                        (SM00:线上清算,SM01:线下清算)	必输
                String payType;
                if ("1".equals(query.detail.payType)) {
                    payType = "SM00";
                } else {
                    payType = "SM01";
                }

                xmlWriter.writeElementString("LQMODE", payType);
//                        <MEMO/>	备注,最大256位	非必输
                xmlWriter.writeElementString("MEMO", query.detail.memo);
//                        <OVERDUEREM/>	逾期说明,1-256位	非必输
                if (StringHelper.hasAnyChar(query.detail.overDueRea)) {
                    xmlWriter.writeElementString("OVERDUEREM", query.detail.overDueRea);
                }
//                <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                        <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输

                xmlWriter.writeElementString("BILLAMT", String.format("%.2f", billAmt));
//                        <CUEAMT/>	提示付款金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("CUEAMT", String.format("%.2f", billAmt));
//                        <AGENTFLAG/>	代理申请标识,4位(固定值PP01)	必输
                xmlWriter.writeElementString("AGENTFLAG", "PP01");
//                        </CONTENT>
//                </RQBODY>
//                </EBCUEPAYTRNRQ>
//                </SECURITIES_MSGSRQV1>

                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBCUEPAYTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trnuId});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCUEPAYTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCUEPAYTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCUEPAYTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBCUEPAYTRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //提示保证
    @Override
    public RetAtsB109BillGuarSubmit D_B109_BillResp_Submit(ReqB109BillGuarSubmit query) throws Exception {
        RetAtsB109BillGuarSubmit retAts = new RetAtsB109BillGuarSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB109BillGuarSubmitDetail detail = new RetAtsB109BillGuarSubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>	请求服务指令消息集	必输
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                <EBGUARNTTRNRQ>	服务标识	必输
                xmlWriter.writeStartElement("EBGUARNTTRNRQ");
//                        <TRNUID/>	客户端交易的唯一流水号
//                建议值为YYYYMMDD+序号，最长30位	必输
                String trnuId = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trnuId);
//                <RQBODY>	消息报文体	非必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//                <TOTALAMT/>	票据总金额, 17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", query.detail.billAmt);
//                        <GUARNTTYPE/>	保证类型,2位(01:出票人提示保证,02:承兑人提示保证,03:背书保证)	必输
                String guarType;
                if ("1".equals(query.detail.guarType)) {
                    guarType = "01";
                } else if ("2".equals(query.detail.guarType)) {
                    guarType = "02";
                } else if ("3".equals(query.detail.guarType)) {
                    guarType = "03";
                } else {
                    throw new Exception("保证类型异常：" + query.detail.guarType);
                }
                xmlWriter.writeElementString("GUARNTTYPE", guarType);
//                        <APPDATE/>	保证申请日期,YYYY-MM-DD	必输
                xmlWriter.writeElementString("APPDATE", Format.Date10Format.format(new Date()));
//                        <APPACCTID/>	被保证人帐号	必输
                xmlWriter.writeElementString("APPACCTID", query.detail.actNum);
//                <ISCIB/>	保证人是否兴业账户代号,1位(Y:是,N:否)	必输
                String isCIB;
                if ("1".equals(query.detail.receSameBank)) {
                    isCIB = "Y";
                } else {
                    isCIB = "N";
                }
                xmlWriter.writeElementString("ISCIB", isCIB);
//                        <GUARNTRACCT>	保证人账户信息	必输
                xmlWriter.writeStartElement("GUARNTRACCT");
//                <ACCTID/>	账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.receAct);
//                        <NAME/>	账户名称,最大60位	必输
                xmlWriter.writeElementString("NAME", query.detail.receName);
//                        <BANKNUM/>	开户行号,最大12位	必输
                xmlWriter.writeElementString("BANKNUM", query.detail.receBnkCode);
//                        </GUARNTRACCT>
                xmlWriter.writeEndElement();
//                <MEMO/>	备注,最大256位	非必输
                xmlWriter.writeElementString("MEMO", query.detail.memo);
//                        <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                        <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", query.detail.billAmt);
//                        </CONTENT>
//                </RQBODY>
//                </EBGUARNTTRNRQ>
//                </SECURITIES_ MSGSRQV1>
                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBGUARNTTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trnuId});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBGUARNTTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBGUARNTTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBGUARNTTRNRQS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBGUARNTTRNRQS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //追索通知
    @Override
    public RetAtsB110BillRecoSubmit D_B110_BillResp_Submit(ReqB110BillRecoSubmit query) throws Exception {
        RetAtsB110BillRecoSubmit retAts = new RetAtsB110BillRecoSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB110BillRecoSubmitDetail detail = new RetAtsB110BillRecoSubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>	请求服务指令消息集	必输
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                        <EBRECRSTRNRQ>	服务标识	必输
                xmlWriter.writeStartElement("EBRECRSTRNRQ");
//                <TRNUID/>	客户端交易的唯一流水号
                String trnuId = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trnuId);
//                建议值为YYYYMMDD+序号，最长30位	必输
//                <RQBODY>	消息报文体	非必输
                xmlWriter.writeStartElement("RQBODY");
//                        <APPDATE/>	追索申请日期,YYYY-MM-DD	必输
                xmlWriter.writeElementString("APPDATE", Format.Date10Format.format(new Date()));
//                        <ACCTFROM>		必输
                xmlWriter.writeStartElement("ACCTFROM");
//                <ACCTID/>	追索人账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.actNum);
//                        </ACCTFROM>
                xmlWriter.writeEndElement();
//                <RECRSTYPE/>	追索类型,4位(RT00:拒付追索,RT01:非拒付追索)	必输
                String recourseType;
                if ("1".equals(query.detail.recourseType)) {
                    recourseType = "RT00";
                } else {
                    recourseType = "RT01";
                }
                xmlWriter.writeElementString("RECRSTYPE", recourseType);
//                        <RECRSAMT/>	追索金额,17位(15整数位,2小数位)	非必输
                double recourseAmt = Double.valueOf(query.detail.recourseAmt);
                xmlWriter.writeElementString("RECRSAMT", String.format("%.2f", recourseAmt));
//                        <ACCTTO>	被追索人信息	必输
                xmlWriter.writeStartElement("ACCTTO");
//                <ACCTID/>	被追索人账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.receAct);
//                        <NAME/>	被追索人账户名称	必输
                xmlWriter.writeElementString("NAME", query.detail.receName);
//                <BANKNUM/>	被追索人开户行号	必输
                xmlWriter.writeElementString("BANKNUM", query.detail.receBnkCode);
//                        <ORGID/>	被追索人组织机构代号	必输
                xmlWriter.writeElementString("ORGID", query.detail.receCode);
//                </ACCTTO>
                xmlWriter.writeEndElement();
//                <RSNCODE/>	追索理由代码,4位(RC00:承兑人被依法宣告破产, RC01:承兑人因违法被责令终止活动) ;
                String recourseCode;
                if ("1".equals(query.detail.recourseCode)) {
                    recourseCode = "RC00";
                } else {
                    recourseCode = "RC01";
                }
                xmlWriter.writeElementString("RSNCODE", recourseCode);
//                <!―非必填字段但不填会报错-->	非必输
//                        <MEMO/>	追索理由备注,最大256位	非必输
                xmlWriter.writeElementString("MEMO", query.detail.memo);
//                        <CONTENT>	票据内容循环体	必输
//                <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                double billAmt = Double.valueOf(query.detail.billAmt);
                xmlWriter.writeElementString("BILLAMT", String.format("%.2f", billAmt));
//                        </CONTENT>
//                </RQBODY>
//                </EBRECRSTRNRQ>
//                </SECURITIES_MSGSRQV1>

                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBRECRSTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trnuId});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBRECRSTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBRECRSTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBRECRSTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBRECRSTRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //同意清偿
    @Override
    public RetAtsB111BillAgreeSubmit D_B111_BillResp_Submit(ReqB111BillAgreeSubmit query) throws Exception {
        RetAtsB111BillAgreeSubmit retAts = new RetAtsB111BillAgreeSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB111BillAgreeSubmitDetail detail = new RetAtsB111BillAgreeSubmitDetail();
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>		必输
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                        <EBDISCHGTRNRQ>		必输
                xmlWriter.writeStartElement("EBDISCHGTRNRQ");
//                        <TRNUID/>	客户端交易的唯一流水号
//                建议值为YYYYMMDD+序号，最长30位	必输
                String trnuId = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trnuId);
//                <RQBODY>		非必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//                <TOTALAMT/>	票据总金额,17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", query.detail.billAmt);
//                        <APPDATE/>	同意清偿申请日期,YYYY-MM-DD	必输
                xmlWriter.writeElementString("APPDATE", Format.Date10Format.format(new Date()));
//                        <ACCTID/>	同意清偿人账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.actNum);
//                        <MEMO/>	备注,最大256位	非必输
                xmlWriter.writeElementString("MEMO", query.detail.memo);
//                        <CONTENT>	票据内容循环体	必输
                xmlWriter.writeStartElement("CONTENT");
//                <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", query.detail.billAmt);
//                        <DISCHGAMT/>	同意清偿金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("DISCHGAMT", query.detail.agreeAmt);
//                        <BIZFLAG/>	业务标识号,1-35位	必输
                xmlWriter.writeElementString("BIZFLAG", query.detail.busiNo);//
//                </CONTENT>
//                </RQBODY>
//                </EBDISCHGTRNRQ>
//                </SECURITIES_MSGSRQV1>
                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBDISCHGTRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trnuId});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDISCHGTRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDISCHGTRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDISCHGTRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBDISCHGTRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }

    //交易撤回
    @Override
    public RetAtsB112BillCancSubmit D_B112_BillResp_Submit(ReqB112BillCancSubmit query) throws Exception {
        return BillWithdrawalReq(query);
    }
    //交易撤回（电票和票据池 通用一个银行接口，一个改都要改）
    public RetAtsB112BillCancSubmit BillWithdrawalReq(ReqB112BillCancSubmit query) throws Exception {
        RetAtsB112BillCancSubmit retAts = new RetAtsB112BillCancSubmit(query.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        while (query.readRecord()) {
            RetAtsB112BillCancSubmitDetail detail = new RetAtsB112BillCancSubmitDetail();
            String[] busiNo = query.detail.busiNo.split("@");
            try {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeaderEn(xmlWriter, "encoding=\"gb2312\"");
//                <SECURITIES_MSGSRQV1>	请求服务指令消息集	必输
                xmlWriter.writeStartElement("SECURITIES_MSGSRQV1");
//                        <EBRECEDETRNRQ>	服务标识	必输
                xmlWriter.writeStartElement("EBRECEDETRNRQ");
//                <TRNUID/>	客户端交易的唯一流水号
//                建议值为YYYYMMDD+序号，最长30位	必输
                String trnuId = getQryTransID();
                xmlWriter.writeElementString("TRNUID", trnuId);
//                <RQBODY>	消息报文体	非必输
                xmlWriter.writeStartElement("RQBODY");
//                        <TOTALCOUNT/>	票据总笔数,8位整数	必输
                xmlWriter.writeElementString("TOTALCOUNT", "1");
//                <TOTALAMT/>	票据总金额,17位(15整数位,2小数位) 	必输
                xmlWriter.writeElementString("TOTALAMT", query.detail.billAmt);
//                        <ACCTID/>	业务撤回申请人账户代号,最大32位	必输
                xmlWriter.writeElementString("ACCTID", query.detail.actNum);
//                        <CONTENT>	票据内容循环体，最多100条	必输
                xmlWriter.writeStartElement("CONTENT");
//                <INDX/>	小序号,4位	必输
                xmlWriter.writeElementString("INDX", "0001");
//                <BILLCODE/>	票据号码,30位	必输
                xmlWriter.writeElementString("BILLCODE", query.detail.billNo);
//                <BILLAMT/>	票据金额,17位(15整数位,2小数位)	必输
                xmlWriter.writeElementString("BILLAMT", query.detail.billAmt);
//                        <BUSINESSTYPE/>	业务标识码,2位,见:附录3-业务类型对照表	必输
                //    撤回类型 1-承兑申请撤回 2-提示收票申请撤回 3-背书转让申请撤回 4-贴现申请撤回 5-质押申请撤回 6-（逾期）提示付款撤回
//    7-出票保证申请撤回 8-承兑保证申请撤回  9-背书保证申请撤回 10-追索通知撤回 11-同意清偿撤回 12-解质押申请撤回
                String cancelType;
                switch (Integer.valueOf(query.detail.cancelType)) {
                    case 1:
                        cancelType = "22";
                        break;
                    case 2:
                        cancelType = "23";
                        break;
                    case 3:
                        cancelType = "24";
                        break;
                    case 4:
                        cancelType = "25";
                        break;
                    case 5:
                        cancelType = "33";
                        break;
                    case 6:
                        cancelType = "35";
                        break;
                    case 7:
                        cancelType = "32";
                        break;
                    case 8:
                        cancelType = "31";
                        break;
                    case 9:
                        cancelType = "30";
                        break;
                    case 10:
                        cancelType = "38";
                        break;
                    case 11:
                        cancelType = "37";
                        break;
                    case 12:
                        cancelType = "34";
                        break;
                    default:
                        throw new Exception("撤回类型未知：" + query.detail.cancelType);
                }
                xmlWriter.writeElementString("BUSINESSTYPE", cancelType);
//                        <BIZFLAG/>	业务标识号,1-35位	必输
                xmlWriter.writeElementString("BIZFLAG", busiNo[1]);
//                <SEQ/>	业务流水号(可操作票据查询返回),1-20位	必输
                xmlWriter.writeElementString("SEQ", busiNo[0]);
//                <APPDATE/>	撤回申请日期,YYYY-MM-DD	必输
                xmlWriter.writeElementString("APPDATE", Format.Date10Format.format(new Date()));
//                        </CONTENT>
//                </RQBODY>
//                </EBRECEDETRNRQ>
//                </SECURITIES_MSGSRQV1>


                xmlWriter.writeEndDocument();
                String xmlSend = writeContentLength(xmlWriter);
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, query.reqHeader.bankCode, "EBRECEDETRNRQ", Format.Date8Format.format(new Date()), query.detail.reqSeqID, trnuId});
                String[] result = sendToBank(xmlSend);
                if (result[0].length() == 0) {
                    String returnXml = result[1].substring(result[1].indexOf("<FOX>"), result[1].length());
                    StringBuilder tmpSbmsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnXml, tmpSbmsg);
                    if (tmpBkReader != null) {
                        String code = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBRECEDETRNRS/STATUS/CODE");
                        if ("0".equals(code)) {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBRECEDETRNRS/RSBODY/XFERPRCSTS/MESSAGE");
                            detail.transState = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBRECEDETRNRS/RSBODY/XFERPRCSTS/XFERPRCCODE");
                            detail.payInfoCode = detail.transState;
                            detail.reqSeqID = query.detail.reqSeqID;
                        } else {
                            detail.respCode = "0";
                            detail.respInfo = tmpBkReader.getFirstText("/FOX/SECURITIES_MSGSRSV1/EBRECEDETRNRS/STATUS/MESSAGE");
                            detail.transState = code;
                            detail.payInfoCode = detail.transState;
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbmsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = result[1];
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
            } finally {
                conn.close();
            }
            retAts.writeDetail(detail);
        }
        retAts.writeEnd();
        return retAts;
    }


    @Override
    public RetAtsB113ProtocolSubmit D_B113_ProtocolResp_Submit(ReqB113ProtocolSubmit query) throws Exception {
        return null;
    }

    @Override
    public RetAtsB119BillRelePledSubmit D_B119_BillResp_Submit(ReqB119BillRelePledSubmit query) throws Exception {
        return null;
    }
}
